package com.jbm;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

import java.math.BigDecimal;
import java.net.InetSocketAddress;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.Executors;

/**
 * Created by root on 18-12-11.
 */
public class shengning implements DoProcess
{
	public String Proc(String json)
	{
		int code = 0;
		String info = "";

		JsonElement content = null;

		Connection conn = null;
		Statement stmt = null;

		try
		{
			JsonParser parser = new JsonParser();
			JsonObject req = (JsonObject) parser.parse(json);

			JsonElement jmethod = req.get("method");

			if ( jmethod == null )
				throw new Exception("方法名不能为空");

			String method = jmethod.toString();

			JsonElement jid = req.get("id");

			String id = null;

			if ( jid != null )
				id = jid.getAsString();

			JsonElement jmobile = req.get("mobile");

			String mobile = null;

			if ( jmobile != null )
				mobile = jmobile.getAsString();

			if ( GDHandler.db_pool != null )
			{
				conn = (Connection) GDHandler.db_pool.take();

//			conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/wycore?"
//					+ "user=root&password=password&useUnicode=true&characterEncoding=UTF8");
				stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
			}else
				throw new Exception("DB error");

			switch (method)
			{
				case "\"get_door_list\"":
				{
					if ( id == null && mobile == null )
						throw new Exception("必须指定身份证号或手机号");

					if ( id == null )
						id = "";
					if ( mobile == null )
						mobile = "";

					String sql = "select distinct aeg.equard_code, aeg.equard_name from entrance_guard eg " +
							"join eguard_key akey on akey.eguard_id = eg.eguard_id " +
							"join eguard_key ekey on ekey.source_id = akey.egkey_id " +
							"join m_gi mgi on mgi.gi_id = eg.gi_id " +
							"join entrance_guard aeg on aeg.gi_id = mgi.prev_id " +
							"where ( ekey.id_card = '"+id+"' or " +
							"ekey.id_card2 = '"+id+"' or " +
							"ekey.mobile = '"+mobile+"' or " +
							"ekey.mobile1 = '"+mobile+"' or " +
							"ekey.mobile2 = '"+mobile+"' ) and aeg.prev_id > 0 ";


					ResultSet rs = stmt.executeQuery(sql);
					rs.last();
					int rcnt = rs.getRow();
					rs.first();

					JsonArray dlist = new JsonArray();

					if ( rcnt > 0 )
					{

						do
						{
							JsonObject door = new JsonObject();

							door.addProperty("door_code", rs.getString("equard_code"));
							door.addProperty("door_name", rs.getString("equard_name"));
							dlist.add(door);
						} while (rs.next());
					}

					rs.close();

					code = 200;
					info = "OK";
					content = dlist;

					break;
				}
				case "\"get_share_list\"":
				{
					if ( id == null )
						throw new Exception("必须指定身份证号");

					String sql = "select distinct ekey.mobile from eguard_key ekey " +
							"join eguard_key skey on ekey.source_id = skey.egkey_id " +
							"where ( skey.id_card = '"+id+"' or " +
							"skey.id_card2 = '"+id+"' ) and ekey.source_id <> ekey.egkey_id";

					ResultSet rs = stmt.executeQuery(sql);
					rs.last();
					int rcnt = rs.getRow();
					rs.first();

					JsonArray slist = new JsonArray();

					if ( rcnt > 0 )
					{
						do
						{
							JsonObject share = new JsonObject();

							share.addProperty("mobile", rs.getString("mobile"));
							slist.add(share);
						} while (rs.next());
					}

					rs.close();

					code = 200;
					info = "OK";
					content = slist;

					break;
				}
				case "\"share\"":
				{
					if ( id == null )
					{
						code = 500;
						info = "身份证号不能为空";
					}else if ( mobile == null )
					{
						code = 500;
						info = "手机号不能为空";
					}else
					{
						String sql = "insert eguard_key ( source_id, eguard_id, create_id, mobile ) " +
								"select egkey_id, 0, 0, '"+mobile+"' from eguard_key ekey " +
								"where ( ekey.id_card = '"+id+"' or " +
								"ekey.id_card2 = '"+id+"' ) and ekey.source_id = ekey.egkey_id";

						int rcnt = stmt.executeUpdate(sql);

						if ( rcnt == 0 )
						{
							code = 500;
							info = id + "无开门权限";
						}else
						{
							code = 200;
							info = mobile + "授权成功";
						}
					}
					break;
				}
				case "\"cancel_share\"":
				{
					if ( id == null )
					{
						code = 500;
						info = "身份证号不能为空";
					}else if ( mobile == null )
					{
						code = 500;
						info = "手机号不能为空";
					}else
					{
						String sql = "delete ekey from eguard_key ekey " +
								"join eguard_key skey on ekey.source_id = skey.egkey_id " +
								"where ( skey.id_card = '"+id+"' or " +
								"skey.id_card2 = '"+id+"' ) and " +
								"skey.source_id = skey.egkey_id and " +
								"ekey.mobile = '"+mobile+"' " +
								"and ekey.source_id <> ekey.egkey_id";

						int rcnt = stmt.executeUpdate(sql);

						if ( rcnt == 0 )
						{
							code = 500;
							info = "未找到对"+mobile+"的授权";
						}else
						{
							code = 200;
							info = mobile + "取消授权成功";
						}
					}
					break;
				}
				case "\"open\"":
				{
					if ( id == null && mobile == null )
						throw new Exception("必须指定身份证号或手机号");

					JsonElement jdoor = req.get("door");

					if ( jdoor == null )
						throw new Exception("必须指定门编号");

					if ( id == null )
						id = "";
					if ( mobile == null )
						mobile = "";

					String door = jdoor.getAsString();

					String sql = "select distinct paeg.equard_code, paeg.open_key, aeg.channel from entrance_guard eg " +
							"join eguard_key akey on akey.eguard_id = eg.eguard_id " +
							"join eguard_key ekey on ekey.source_id = akey.egkey_id " +
							"join m_gi mgi on mgi.gi_id = eg.gi_id " +
							"join entrance_guard aeg on aeg.gi_id = mgi.prev_id " +
							"join entrance_guard paeg on aeg.prev_id = paeg.eguard_id " +
							"where ( ekey.id_card = '"+id+"' or " +
							"ekey.id_card2 = '"+id+"' or " +
							"ekey.mobile = '"+mobile+"' or " +
							"ekey.mobile1 = '"+mobile+"' or " +
							"ekey.mobile2 = '"+mobile+"' ) and " +
							"aeg.prev_id > 0 and " +
							"(aeg.equard_code = '"+door+"' or paeg.equard_code = '"+door+"')";

					ResultSet rs = stmt.executeQuery(sql);
					rs.last();
					int rcnt = rs.getRow();
					rs.first();

					int total = 0;

					if ( rcnt > 0 )
					{
						do
						{
							String ip = rs.getString("equard_code");
							int b_id = rs.getInt("open_key");
							int channel = rs.getInt("channel");

							ConnectAgent ca = (ConnectAgent)GDHandler.gd_pool.Get(null,null,ip);

							if ( ca != null )
							{
								total ++;
								ca.Send(Guard.getOpenCMD(b_id,channel));
							}
						} while (rs.next());
					}

					rs.close();

					if ( total > 0 )
					{
						code = 200;
						info = door + "开门成功";
					}else
					{
						code = 500;
						info = door + "开门失败";
					}
					break;
				}
				case "\"black\"":
				{
					JsonElement jcard = req.get("card");
					JsonElement jips = req.get("ips");

					if ( jcard == null )
						throw new Exception("必须指定Card编号");

					if ( jips == null )
						throw new Exception("ips is null");

					int card = jcard.getAsInt();
					String ips = jips.getAsString();
					String[] mip = ips.split(",");

					int join = 0;

					for ( String ip:mip)
					{
						String [] tip = ip.split(":");

						ConnectAgent ca = null;

						ca = (ConnectAgent) GDHandler.gd_pool.Get(null, null, tip[0]);
						if (ca != null)
						{
							join++;
							ca.Send(Guard.getBlackCMD("join", Integer.parseInt(tip[1]), card));
						}
					}

					code = 200;
					info = "join "+join;

					break;
				}
				case "\"white\"":
				{
					JsonElement jcard = req.get("card");
					JsonElement jips = req.get("ips");

					if ( jcard == null )
						throw new Exception("必须指定Card编号");

					if ( jips == null )
						throw new Exception("ips is null");

					int card = jcard.getAsInt();
					String ips = jips.getAsString();
					String[] mip = ips.split(",");

					int remove = 0;

					for ( String ip:mip)
					{
						String [] tip = ip.split(":");

						ConnectAgent ca = null;

						ca = (ConnectAgent) GDHandler.gd_pool.Get(null, null, tip[0]);
						if (ca != null)
						{
							remove++;
							ca.Send(Guard.getBlackCMD("remove", Integer.parseInt(tip[1]), card));
						}
					}

					code = 200;
					info = "remove "+remove;

					break;
				}
				default:
					code = 404;
					info = "不支持的方法名:"+method;
					break;
			}
		}catch (Exception e)
		{
			code = 500;
			info = e.getMessage();

			if ( info == null )
				info = "Failed";

			content = null;
		}

		try
		{
			if (stmt != null)
				stmt.close();

			if ( conn != null )
				GDHandler.db_pool.put(conn);
		}catch (Exception e)
		{
		}

		JsonObject response = new JsonObject();

		response.addProperty("code",code);
		response.addProperty("errorinfo",info);
		if ( content != null )
			response.add("content",content);

		return response.toString();
	}

	public void Begin()
	{
		if ( GDHandler.db_pool != null )
		{
			Connection conn = null;
			Statement stmt = null;

			try
			{
				conn = (Connection) GDHandler.db_pool.take();
				stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);

				String sql = "update entrance_guard set online_status = 'offline' where " +
						"type = 'board'";

				stmt.executeUpdate(sql);

				stmt.close();
				stmt = null;

				GDHandler.db_pool.add(conn);
			}catch (Exception e)
			{
			}
		}

		try
		{
			IoAcceptor acceptor = new NioSocketAcceptor();
			acceptor.getFilterChain().addLast("logger", new LoggingFilter());
			acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new GDCodeFactory("UTF-8")));
			acceptor.getFilterChain().addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool()));
			// 设置读取数据的缓冲区大小
			acceptor.getSessionConfig().setReadBufferSize(4096);
			// 读写通道10秒内无操作进入空闲状态
			acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
			acceptor.setHandler(new GDHandler());
			acceptor.bind(new InetSocketAddress(8000));
		}catch (Exception e)
		{}
	}

	public String UNPay( String json )
	{
		SysLog.g_syslog.MakeLog(SysLog.SYS_LOG_LEVEL_DEBUG,"UNPay");
		JsonParser parser = new JsonParser();
		JsonObject req = (JsonObject) parser.parse(json);

		Connection conn = null;
		Statement stmt = null;
		int code = 500;
		String info = "FAILED";

		try
		{
			if ( GDHandler.db_pool != null )
			{
				conn = (Connection) GDHandler.db_pool.take();

//			conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/wycore?"
//					+ "user=root&password=password&useUnicode=true&characterEncoding=UTF8");
				stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
			}else
				throw new Exception("DB error");

			conn.setAutoCommit(false);

			String sql = "update payorder set status = 'paied', pay_date = now(), unserial = '"+req.get("queryId").getAsString()+"' " +
					"where status = 'unpay' and porder_code = '"+req.get("orderId").getAsString()+"'";
			int update = stmt.executeUpdate(sql);

			if ( update == 0 )
				throw new Exception("update payorder to paied error");

			sql = "select amount,user_id,ser_type from payorder where porder_code = '"+req.get("orderId").getAsString()+"'";
			ResultSet rs = stmt.executeQuery(sql);
			rs.next();
			BigDecimal amount = rs.getBigDecimal("amount");
			int user_id = rs.getInt("user_id");
			String sertype = rs.getString("ser_type");
			rs.close();

			if ( user_id != 0 && sertype.equals("wy") )
			{
				sql = "insert into payment_log( contract_no, amount, pay_date, pay_type, pay_type_name, pay_method, user_id) " +
						"select contract, amount, pay_date, 'manage', '物业费', 1, user_id from payorder where porder_code = '" + req.get("orderId").getAsString() + "'";
				stmt.executeUpdate(sql);

				sql = "select egcard, manage_fee, manage_fee_date, manage_fee_rate, block_data from user where user_id = " + user_id;
				rs = stmt.executeQuery(sql);
				rs.next();
				BigDecimal manage_fee = rs.getBigDecimal("manage_fee");
				Date manage_fee_date = rs.getDate("manage_fee_date");
				int manage_fee_rate = rs.getInt("manage_fee_rate");
				String block_data = rs.getString("block_data");
				int egcard = rs.getInt("egcard");
				rs.close();

				int ms = manage_fee_rate == 1 ? 1 :
						manage_fee_rate == 2 ? 3 :
								manage_fee_rate == 3 ? 12 : 0;

				if (ms != 0)
				{
					amount = amount.multiply(new BigDecimal(ms));
					amount = amount.divide(manage_fee, 2);

					int addms = amount.intValue();

					Calendar rightNow = Calendar.getInstance();
					rightNow.setTime(manage_fee_date);
					rightNow.add(Calendar.MONTH, addms);

					int year = rightNow.get(Calendar.YEAR);
					int month = rightNow.get(Calendar.MONTH);
					int day = rightNow.get(Calendar.DAY_OF_MONTH);

					SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

					String mfdate = format.format(rightNow.getTime());

					String hdate = String.format("%04x%02x%02x", year, month + 1, day);
					hdate = hdate.toUpperCase();
					hdate = hdate.substring(2, 4) + hdate.substring(0, 2) + hdate.substring(4);

					block_data = block_data.substring(0, 24) + hdate;

					sql = "update user set manage_fee_date = '" + mfdate + "', block_data = '" + block_data + "' where user_id = " + user_id;
					update = stmt.executeUpdate(sql);

					if (update == 0)
						throw new Exception("update user error");

					sql = "update payorder set status = 'adddate' " +
							"where status = 'paied' and porder_code = '" + req.get("orderId").getAsString() + "'";
					update = stmt.executeUpdate(sql);

					if (update == 0)
						throw new Exception("update payorder to adddate error");
				}
				sql = "select distinct reg.equard_code, reg.open_key from entrance_guard eg " +
						"join eguard_key akey on akey.eguard_id = eg.eguard_id " +
						"join eguard_key ekey on ekey.source_id = akey.egkey_id " +
						"join m_gi mgi on mgi.gi_id = eg.gi_id " +
						"join entrance_guard aeg on aeg.gi_id = mgi.prev_id " +
						"join entrance_guard reg on reg.eguard_id = aeg.prev_id " +
						"join user u on ekey.id_card = u.idnumber " +
						"where u.user_id = "+user_id+" and aeg.prev_id > 0 ";
				rs = stmt.executeQuery(sql);
				rs.last();
				int rcnt = rs.getRow();
				rs.first();

				if ( rcnt > 0 )
				{
					do
					{
						String ip = rs.getString("equard_code");
						int gid = rs.getInt("open_key");

						ConnectAgent ca = null;

						ca = (ConnectAgent)GDHandler.gd_pool.Get(null,null,ip);
						if ( ca != null )
							ca.Send(Guard.getBlackCMD("remove",gid,egcard));
					} while (rs.next());
				}

				rs.close();
			}

			conn.commit();

			code = 200;
			info = "OK";
		}catch (Exception e)
		{
			SysLog.g_syslog.MakeLog(SysLog.SYS_LOG_LEVEL_DEBUG,"Error:%s",e.getMessage());
			try
			{
				if ( conn != null && !conn.getAutoCommit())
					conn.rollback();
			}catch (Exception ee)
			{}

			code = 500;
			info = e.getMessage();
		}

		try
		{
			if (stmt != null)
				stmt.close();

			if ( conn != null )
			{
				conn.setAutoCommit(true);
				GDHandler.db_pool.put(conn);
			}
		}catch (Exception e)
		{
		}

		JsonObject response = new JsonObject();

		response.addProperty("code",code);
		response.addProperty("errorinfo",info);

		return response.toString();
	}
}
